home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / zm16src.lzh / PHONE.C < prev    next >
C/C++ Source or Header  |  1988-05-19  |  15KB  |  874 lines

  1. /*
  2.  * Phone dialing Module (from XMDM)
  3.  *
  4.  *
  5.  *        Jwahar Bammi
  6.  *            usenet: mandrill!bammi@{decvax,sun}.UUCP
  7.  *            csnet:  bammi@mandrill.ces.CWRU.edu
  8.  *            arpa:   bammi@mandrill.ces.CWRU.edu
  9.  *            CompuServe: 71515,155
  10.  */
  11.  
  12. #include "config.h"
  13.  
  14. #ifndef STANDALONE
  15. #ifdef PHONES
  16.  
  17. #include "zmdm.h"
  18.  
  19. typedef int WORD;
  20. typedef long LONG;
  21.  
  22.  
  23. #define sendchar(c)    Bconout(1, c);
  24. #define clear_screen()  Bconws("\033H\033J")
  25. #define inv()        EscSeq('p')
  26. #define normal()    EscSeq('q')
  27. #define mvto(r,c)    EscSeq('Y');Bconout(2, r+040);Bconout(2, c+040)
  28. #define ceol()        EscSeq('K')
  29. #define show_cursor()    EscSeq('e')
  30. #define hide_cursor()    EscSeq('f')
  31.  
  32. typedef struct _dir {        /* The Directory type */
  33.     char    *name;        /* Name (11 chars max) */
  34.     char     *number;    /* Phone # (24 chars max) */
  35.     WORD    baud;        /* baud Rate         */
  36.     struct _dir *next;    /* Ptr to next entry */
  37. } *DIR;
  38.  
  39.  
  40.      /* External Variables */
  41. extern WORD speed;        /* Current Baud Rate */
  42. extern WORD Baudrate;
  43. extern BAUDS vbauds[];
  44.  
  45. WORD dchanged = 0;            /* Has the directory been updated */
  46.  
  47.      /* Globals */
  48. static WORD ndir = 0;            /* # of entries in phone directory   */
  49. static DIR directory = (DIR)NULL;    /* The phone directory           */
  50. static DIR lastdir   = (DIR)NULL;     /* Pointer to last entry         */
  51. static char *dirfile = (char *)NULL;    /* Name of file conatining directory */
  52. static WORD rflag = 0;            /* Read directory as yet??          */
  53.  
  54.  
  55. /*
  56.  * Read the Telephone directory
  57.  *  returns -2 on read error
  58.  *        -1 if cancelled
  59.  *        -3 if file not found
  60.  *         n # of entries  otherwise
  61.  */
  62. WORD readdir()
  63. {
  64.     register char *filename;
  65.     register WORD handle;
  66.     register WORD nentries;
  67.     register DIR last;
  68.     register DIR present;
  69.     extern char *preadl();
  70.     extern char *malloc();
  71.     
  72.     Bconws("Enter Filename of Phone Directory or <CR> to Cancel: ");
  73.  
  74.     if((filename = preadl()) == (char *)NULL)
  75.         /* Cancelled */
  76.         return -1;
  77.  
  78.     if((dirfile = malloc(strlen(filename)+1)) == (char *)NULL)
  79.     {
  80.         /* Out of memory */
  81.         Bconws("Out of Memory\r\n");
  82.         return 0;
  83.     }
  84.     strcpy(dirfile,filename);
  85.     
  86.  
  87.     if((handle = Fopen(filename,0)) < 0)
  88.         /* File does not exist */
  89.         return -3;
  90.     
  91.     /* Read in the file */
  92.     if(Fread(handle, 2L, &ndir) != 2L)
  93.     {
  94.         Bconws("Error Reading ");
  95.         Bconws(filename);
  96.         Bconws("\r\n");
  97.         Fclose(handle);
  98.         return -2;
  99.     }
  100.  
  101.     /* Read in the directory */
  102.     last = (DIR)NULL;
  103.     directory = (DIR)NULL;
  104.     lastdir = (DIR)NULL;
  105.     rflag = 1;
  106.     
  107.     for(nentries = 0; nentries < ndir; nentries++)
  108.     {
  109.         /* Allocate an entry */
  110.         if((present = (DIR)malloc(sizeof(struct _dir))) == (DIR)NULL)
  111.         {
  112.             /* Out of memory */
  113.             Bconws("Out of Memory\r\n");
  114.             Fclose(handle);
  115.             return nentries;
  116.         }
  117.         
  118.         if((present->name = malloc(12)) == (char *)NULL)
  119.         {
  120.             /* Out of memory */
  121.             Bconws("Out of Memory\r\n");
  122.             Fclose(handle);
  123.             return nentries;
  124.         }
  125.  
  126.         if((present->number = malloc(25)) == (char *)NULL)
  127.         {
  128.             /* Out of memory */
  129.             Bconws("Out of Memory\r\n");
  130.             Fclose(handle);
  131.             return nentries;
  132.         }
  133.  
  134.         present->next = (DIR)NULL;
  135.         
  136.         /* Read in the entry */
  137.         if(Fread(handle,11L,present->name) != 11L)
  138.         {
  139.             Bconws("Error Reading ");
  140.             Bconws(filename);
  141.             Bconws("\r\n");
  142.             Fclose(handle);
  143.             rflag = 0;
  144.             freedir(directory);
  145.             return -2;
  146.  
  147.         }
  148.  
  149.         if(Fread(handle,24L,present->number) != 24L)
  150.         {
  151.             Bconws("Error Reading ");
  152.             Bconws(filename);
  153.             Bconws("\r\n");
  154.             Fclose(handle);
  155.             rflag = 0;
  156.             freedir(directory);
  157.             return -2;
  158.         }
  159.  
  160.         if(Fread(handle,2L,&(present->baud)) != 2L)
  161.         {
  162.             Bconws("Error Reading ");
  163.             Bconws(filename);
  164.             Bconws("\r\n");
  165.             Fclose(handle);
  166.             rflag = 0;
  167.             freedir(directory);
  168.             return -2;
  169.         }
  170.         
  171.  
  172.         present->name[11] = '\0';
  173.         present->number[24] = '\0';
  174.  
  175.         /* Link it on with the directory */
  176.         if(last == (DIR)NULL)
  177.             /* first entry */
  178.             directory = present;
  179.         else
  180.             last->next = present;
  181.         
  182.         last = present;
  183.     }
  184.     lastdir = last;
  185.     
  186.     return nentries;    
  187. }
  188.  
  189. /*
  190.  * Free space allocated to a phone directory
  191.  *
  192.  */
  193. freedir(dir)
  194. register DIR dir;
  195. {
  196.     register DIR next;
  197.     register DIR present;
  198.  
  199.     for(present = dir; present != (DIR)NULL; present = next)
  200.     {
  201.         next = present->next;
  202.         free(present->name);
  203.         free(present->number);
  204.         free(present);
  205.     }
  206.     
  207.     if(dirfile != (char *)NULL)
  208.     {
  209.         free(dirfile);
  210.         dirfile   = (char *)NULL;
  211.     }
  212.     
  213.     directory = (DIR)NULL;
  214.     lastdir      = (DIR)NULL;
  215.     ndir      = 0;
  216.     rflag      = 0;
  217. }
  218.  
  219. /*
  220.  * Write out the phone directory
  221.  *  -returns 0 on success 1 otherwise
  222.  *
  223.  */
  224. WORD writedir()
  225. {
  226.     register DIR dir;
  227.     register WORD fd;
  228.     
  229.     if((rflag == 0) || (dirfile == (char *)NULL) || (dchanged == 0))
  230.         /* Nothing to Save */
  231.         return 0;
  232.  
  233.     /* Create/Open file for write - overwrite if it exists */
  234.     if ((fd = Fcreate(dirfile,0)) < 0) /* Will fail if file is present */
  235.     {
  236.         /* Overwrite existing file */
  237.         if((fd = Fopen(dirfile,1)) < 0)
  238.         {
  239.             Bconws("Cannot Open ");
  240.             Bconws(dirfile);
  241.             Bconws("\r\n");
  242.             return 1;
  243.         }
  244.     }
  245.  
  246.     if(Fwrite(fd,2L,&ndir) != 2L)
  247.     {
  248.         Bconws("Error Writing ");
  249.         Bconws(dirfile);
  250.         Bconws("\r\n");
  251.         Fclose(fd);
  252.         return 1;
  253.     }
  254.     
  255.     for(dir = directory; dir != (DIR)NULL; dir = dir->next)
  256.     {
  257.         if(Fwrite(fd,11L,dir->name) != 11L)
  258.         {
  259.             Bconws("Error Writing ");
  260.             Bconws(dirfile);
  261.             Bconws("\r\n");
  262.             Fclose(fd);
  263.             return 1;
  264.         }
  265.  
  266.         if(Fwrite(fd,24L,dir->number) != 24L)
  267.         {
  268.             Bconws("Error Writing ");
  269.             Bconws(dirfile);
  270.             Bconws("\r\n");
  271.             Fclose(fd);
  272.             return 1;
  273.         }
  274.  
  275.         if(Fwrite(fd,2L,&(dir->baud)) != 2L)
  276.         {
  277.             Bconws("Error Writing ");
  278.             Bconws(dirfile);
  279.             Bconws("\r\n");
  280.             Fclose(fd);
  281.             return 1;
  282.         }
  283.     }
  284.     
  285.     Fclose(fd);
  286.     return 0;
  287. }
  288.  
  289. /*
  290.  * Show the phone directory
  291.  * return the entry # or -1 if cancelled
  292.  *
  293.  */
  294. WORD showdir()
  295. {
  296.     register WORD first, last;
  297.     register WORD n;
  298.     register char *line;
  299.     extern WORD atoi();
  300.     extern char *preadl();
  301.     
  302.     first = 0;
  303.  
  304.     while(1)
  305.     {
  306.         again:
  307.         clear_screen();
  308.  
  309.         mvto(0,19);
  310.         Bconws("Phone Directory: ");
  311.         Bconws(dirfile);
  312.         Bconws("  ");
  313.         printf("%d",ndir); fflush(stdout);
  314.         Bconws(" Entry(s)");
  315.  
  316.         last = (ndir < (first + 44)) ? ndir : first + 44;
  317.         putdir(first,last);
  318.         
  319.         /* mvto(25,0); */
  320.         Bconws("\r\n");
  321.         inv();
  322.         Bconws("Enter a # or <SPACE><RETURN> for Next Page or <RETURN> to Cancel:");
  323.         normal();
  324.         Bconout(2, ' ');
  325.         if((line = preadl()) == (char *)NULL)
  326.         {
  327.             return -1;
  328.         }
  329.         
  330.         if(isdigit(*line))
  331.         {
  332.             if((n = atoi(line)) >= ndir)
  333.             {
  334.                 Bconws("Invalid Number ");
  335.                 hit_key();
  336.                 goto again;
  337.             }
  338.             
  339.             return n;
  340.         }
  341.  
  342.         if(last == ndir)
  343.             first = 0;
  344.         else
  345.             first += 44;
  346.     }
  347. }
  348.  
  349. /*
  350.  * Put up directory entries on the screen
  351.  *
  352.  */
  353. putdir(first,last)
  354. register WORD first;
  355. register WORD last;
  356. {
  357.     register DIR dir;
  358.     register WORD row;
  359.     extern DIR nth();
  360.     
  361.     /* Find the first entry */
  362.     dir = nth(first);
  363.     row = (first % 44) + 1;
  364.  
  365.     hide_cursor();
  366.     inv();
  367.     for(; first < last; first++)
  368.     {
  369.         mvto(row,((first & 1)?41:0));
  370.         if(first < 10)
  371.             Bconout(2, ' ');
  372.         printf("%d",first); fflush(stdout);
  373.         Bconout(2, '|');
  374.         putstr(dir->name,11);
  375.         Bconout(2, '|');
  376.         putstr(dir->number,24);
  377.         dir = dir->next;
  378.         if(first & 1)
  379.             row++;
  380.     }
  381.  
  382.     if(first & 1)
  383.     {
  384.         mvto(row,41);
  385.         Bconws("  |           |                        ");
  386.         row++;
  387.     }
  388.  
  389.     for(; row < 23; row++)
  390.     {
  391.         Bconws("  |           |                        ");
  392.         mvto(row,41);
  393.         Bconws("  |           |                        ");
  394.     }
  395.  
  396.     normal();
  397.     show_cursor();
  398. }
  399.  
  400. /*
  401.  * Put a string padding to len on screen
  402.  */
  403. putstr(s,l)
  404. register char *s;
  405. register WORD l;
  406. {
  407.     register WORD pad;
  408.  
  409.     Bconws(s);
  410.     if((pad = l - strlen(s)) <= 0)
  411.         return;
  412.     for(; pad > 0; pad--)
  413.         Bconout(2, ' ');
  414. }
  415.  
  416.  
  417. /*
  418.  * Return the nth entry in the phone directory
  419.  *
  420.  */
  421. DIR nth(n)
  422. register WORD n;
  423. {
  424.     register WORD i;
  425.     register DIR dir;
  426.     
  427.     for(i = 0, dir = directory; (dir != (DIR)NULL) & (i < n);
  428.         i++, dir = dir->next)
  429.         /* Skip */;
  430.     return(dir);
  431. }
  432.  
  433. /*
  434.  * Add a entry in the phonebook
  435.  */
  436. addi